package com.icss.mqsp.quartz.util;

import com.icss.mqsp.data.build.util.RQDataUtil;
import com.icss.mqsp.util.AnalyseJsonUtil;
import com.icss.mqsp.util.DataUtil;
import com.icss.pangu.logging.Log;
import com.icss.pangu.logging.LogFactory;
import com.runqian.report4.usermodel.Context;
import com.runqian.report4.usermodel.Engine;
import com.runqian.report4.usermodel.IReport;
import com.runqian.report4.usermodel.Macro;
import com.runqian.report4.usermodel.MacroMetaData;
import com.runqian.report4.usermodel.Param;
import com.runqian.report4.usermodel.ParamMetaData;
import com.runqian.report4.util.ReportUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class AutoCache
{
  private static Log log = LogFactory.getLog(AutoCache.class);
  
  public static boolean createDsCache()
  {
    log.info("开始自动缓存生成");
    JSONObject cacheJson = AnalyseJsonUtil.getPageJson("autoCache");
    JSONArray jsArray = cacheJson.getJSONArray("cache");
    log.info("需要生成缓存内容" + jsArray.toString());
    for (int i = 0; i < jsArray.size(); i++)
    {
      JSONObject js = jsArray.getJSONObject(i);
      String pageid = js.getString("pid");
      String params = js.getString("params");
      Map<String, String> conditionMap = DataUtil.jsonToMap(params);
      buildCachePageData(pageid, conditionMap);
      log.info("pageid = " + pageid + "conditionMap=" + conditionMap.toString());
    }
    return true;
  }
  
  public static void buildCachePageData(String pid, Map<String, String> conditionMap)
  {
    List<com.icss.mqsp.model.ReportDefine> reportDefineList = AnalyseJsonUtil.getDefine(pid);
    
    com.icss.mqsp.model.ReportDefine rd = null;
    for (int i = 0; i < reportDefineList.size(); i++)
    {
      rd = (com.icss.mqsp.model.ReportDefine)reportDefineList.get(i);
      
      log.info("rd = " + rd.getId() + "conditionMap=" + conditionMap.toString());
      getIReport(rd.getId(), conditionMap);
    }
  }
  
  private static void getIReport(String raqPath, Map<String, String> condition)
  {
    com.runqian.report4.model.ReportDefine rd = RQDataUtil.getReportDefine(raqPath);
    IReport iReport = null;
    Map paramMap = null;
    Context cxt = new Context();
    String reportName = raqPath;
    

    ParamMetaData pmd = rd.getParamMetaData();
    if (pmd != null) {
      for (int i = 0; i < pmd.getParamCount(); i++) {
        if (pmd.getParam(i).getParamType() == 1)
        {
          log.debug("过滤掉的动态参数：" + pmd.getParam(i).getParamName());
        }
        else
        {
          String paramOrMocrName = pmd.getParam(i).getParamName();
          String paramVal = (String)condition.get(paramOrMocrName);
          cxt.setParamValue(paramOrMocrName, paramVal);
          log.debug("参数名=" + paramOrMocrName + "，参数值=" + (String)condition.get(paramOrMocrName));
        }
      }
    }
    MacroMetaData mmd = rd.getMacroMetaData();
    if (mmd != null) {
      for (int i = 0; i < mmd.getMacroCount(); i++) {
        if (mmd.getMacro(i).getType() == 1)
        {
          log.debug("过滤掉的动态宏：" + mmd.getMacro(i).getMacroName());
        }
        else
        {
          String paramOrMocrName = mmd.getMacro(i).getMacroName();
          String macroValue = null;
          if ((condition.get(paramOrMocrName) != null) && (((String)condition.get(paramOrMocrName)).length() > 1) && (((String)condition.get(paramOrMocrName)).startsWith("0"))) {
            macroValue = "'" + (String)condition.get(paramOrMocrName) + "'";
          } else if (condition.get(paramOrMocrName) == null) {
            macroValue = "0";
          } else {
            macroValue = (String)condition.get(paramOrMocrName);
          }
          cxt.setMacroValue(paramOrMocrName, macroValue);
          
          log.debug("【宏name=" + paramOrMocrName + "，value=" + macroValue);
        }
      }
    }
    Engine engine = new Engine(rd, cxt);
    List macroList = RQDataUtil.getParams(rd);
    StringBuffer ratPath = new StringBuffer();
    raqPath = raqPath.replace('/', '_');
    ratPath.append(CacheUtil.getRatAutoDir());
    ratPath.append("/" + CacheUtil.updateTime + "_" + raqPath);
    for (int i = 0; i < macroList.size(); i++)
    {
      paramMap = (Map)macroList.get(i);
      ratPath.append("_" + (String)condition.get(paramMap.get("name")));
    }
    ratPath.append(".rat");
    File ratFile = new File(ratPath.toString());
    if (!ratFile.exists())
    {
      log.info("计算生成IReport对象[" + raqPath + "]..开始");
      try
      {
        iReport = engine.calc();
      }
      catch (Exception e)
      {
        iReport = null;
        log.error(e.toString());
        log.debug("计算生成IReport对象[" + raqPath + "]..失败");
      }
      if (iReport != null) {
        try
        {
          buildRatFile(ratPath.toString(), CacheUtil.getRatAutoDir(), iReport);
        }
        catch (Exception e)
        {
          log.error(e.toString());
          log.debug("计算生成IReport对象[" + raqPath + "]缓存..失败");
        }
      }
    }
  }
  
  private static void buildRatFile(String ratUrl, String ratDirUrl, IReport iReport)
  {
    log.info("构造rat文件[" + ratUrl + "]");
    File ratFile = new File(ratUrl);
    try
    {
      if (ratFile.exists())
      {
        ratFile.delete();
        ratFile.createNewFile();
      }
      else
      {
        log.info("目录不存在=" + ratDirUrl);
        File ratDirFile = new File(ratDirUrl);
        if (!ratDirFile.exists()) {
          ratDirFile.mkdirs();
        }
        ratFile.createNewFile();
      }
    }
    catch (Exception e)
    {
      log.error(e.toString());
    }
    FileOutputStream outputStream = null;
    try
    {
      log.info("文件写入...开始");
      outputStream = new FileOutputStream(ratFile);
      ReportUtils.write(outputStream, iReport);
      log.info("文件写入...结束");
    }
    catch (Exception e)
    {
      log.error(e.toString());
      try
      {
        ratFile.delete();
      }
      catch (Exception e1)
      {
        e1.printStackTrace();
      }
      try
      {
        outputStream.close();
      }
      catch (IOException s)
      {
        log.error(s.toString());
      }
    }
    finally
    {
      try
      {
        outputStream.close();
      }
      catch (IOException e)
      {
        log.error(e.toString());
      }
    }
  }
}
